#include <iostream>

int main()
{
    // 2.1.1定义变量

    //定义变量基本形式：类型说明符  变量名;

    // int sum = 1, value;
    // Sales_item item;
    // string是一种库类型，表示一个可变长的字符序列
    // std::string book("0-201-78345-x"); // book通过一个string字面值初始化

    //初始化
    //当对象在创建时获得一个特定的值，我们说这个对象被初始化
    //初始化与赋值
    //初始化：创建变量时赋予其一个初始值
    //赋值的含义是把对象的当前值檫除，而以一个新的新值来替代

    //列表初始化
    //定义一个名为units_sold的int变量并初始化为0
    // int unuts_sold1 = 0;
    // int unuts_sold2 = {0};
    // int unuts_sold3{0};//列表初始化 c++新标准
    // int unuts_sold4(0);
    // std::cout << unuts_sold4 << std::endl;

    // //列表初始化特点：
    // //使用列表初始化且初始化值存在丢失信息的风险，则编译器将报错
    // long double ld= 3.1415926536;
    // // int a{ld},b={ld};   //h.cpp:30:20: warning: narrowing conversion of 'ld'from 'long double' to 'int' inside { } [-Wnarrowing]
    //                        //编译错误，因为存在丢失信息的危险
    // int c(ld),d=(ld);

    //默认初始化
    //如果定义变量没有指定初值，则变量被默认初始化，此时变量被赋予了“默认值”,定义于任何函数体之外的变量被初始化为0
    //注意：定义在函数体内部的内置类型变量不被初始化
    //     一个未被初始化的内置类型的变量的值是未定义的，如果试图拷贝或以其他形式访问此类值将引发错误

    // unsigned char i=256;    //256超过了unsigned char的范围 warning: unsigned conversion from 'int' to 'unsigned char' changes value from '256' to '0' [-Woverflow]

    // 2.2.1节练习
    //  练习2.9：解释下列定义的含义。对于非法的定义，请说明错在何处并将其改正。
    //  std::cin>>int input_value;//未声明变量，无法初始化 int input_value;std::cin>>input_value;
    //  int i={3.14};             //会发生警告，造成小数丢失
    //  double salary=wage=9999.99;//wage未声明 double salary=9999.99,wage=9999.99
    //  int i=3.14;//i初始化为3，小数部分丢失

    // 【解答】(a)是错误的，输入运算符的右侧需要一个明确的变量名称，而非定义变量的语句，改正后的结果是：[插图]
    //(b)引发警告，该语句定义了一个整型变量i，但是试图通过列表初始化的方式把浮点数3.14赋值给i，这样做将造成小数部分丢失，是一种不被建议的窄化操作。
    //(c)是错误的，该语句试图将9999.99分别赋值给salary和wage，但是在声明语句中声明多个变量时需要用逗号将变量名隔开，而不能直接用赋值运算符连接，改正后的结果是：[插图]
    //(d)引发警告，该语句定义了一个整型变量i，但是试图把浮点数3.14赋值给i，这样做将造成小数部分丢失，与(b)一样是不被建议的窄化操作。

    // 练习2.10：下列变量的初值分别是什么
    // std::string global_str;           //空串
    // int global_int;                   //0
    // int main(){
    //          int local_int;               //按标准不初始化，但是编译器还是初始化为0
    //          std::string local_str;      //空串
    //          int local_int1=local_int;
    //          std::string local_str1=local_str;
    //     // }
    //     std::cout<<local_int1<<" || "<<local_str1<<std::endl;

    // 2.2.2变量声明和定义的关系
    //允许把程序拆分成多个逻辑部分来编写
    // c++语言支持分离式编译机制，该机制允许把程序分割为若干个文件，每个文件可被独立编译
    // eg.   std::cout和std::cin，他们定义与标准库，却能被我们写的程序使用

    // c++语言将声明与定义区分开来
    //声明：使得名字为程序所知，一个文件如果想使用别处定义的名字则必须包含对那个名字的声明。
    //定义：负责创建于名字关联的实体。申请存储空间，也可能为变量赋一个初始值

    // //声明一个变量而非定义它，在变量名前添加关键字extern,而且不要显示地初始化变量
    // extern int i;         //声明i而非定义i
    // int j;                //声明并定义i
    // extern int pi = 3.14; //定义

    // 2.2.2节练习
    // 练习2.11：指出下面的语句是声明还是定义：
    // extern int ix = 1024; //定义
    // int iy;               //声明并且定义
    // extern int iz;        //声明

    // 2.2.4 名字的作用域
    // 2.2.4 节练习
    //  练习2.13：下面程序中j的值是多少？
    // int i = 42;
    // // int main()
    // {
    //     int i = 100;
    //     int j = i; //100 就近
    // }
    // 练习2.14：下面的程序合法吗？如果合法，它将输出什么？
    int i = 100, sum = 0;
    for (int i = 0; i != 10; i++)
        sum += i;
    std::cout << i << " " << sum << std::endl;//i输出外层作用域的i值，sum是内层作用域i从0累加到9的值
    

    return 0;
}